#ifndef BEZIER_CURVE_H
#define BEZIER_CURVE_H

#include "Vector3.h"
#include "MathFunctions.h"
#include <vector>

class BezierCurve
{

private:
	std::vector<Vector3<float>> controlPoints;							// The Control Points that calculate the Curve
	std::vector<Vector3<float>> pointsOnTheCurve;						// Points that are a part of the curve
	static const unsigned __int8 NUMBER_OF_TIMESTEPS = 20;			// Number of time steps throughout the curve

public:

	BezierCurve(void)
	{

	}

	// Constructor
	BezierCurve(std::vector<Vector3<float>> points)
	{
		controlPoints = points;
	}

	// Deconstructor
	~BezierCurve(void)
	{

	}

	// Create points on the Curve
	void CreatePoints()
	{

		unsigned __int8 CONTROL_POINT_COUNT = controlPoints.size();
		unsigned __int8 n = CONTROL_POINT_COUNT - 1;

		unsigned __int8 i,j;			

		// Time Step through the Curve
		const float timeStepIncrement = 1.0f / NUMBER_OF_TIMESTEPS;
		float currentTimeStep = 0;	


		// Factorials 
		float nFactorial = Factorial(n);

		Vector3<float> tempVector;

		for(i = 0; i < NUMBER_OF_TIMESTEPS + 1; i++)
		{
			tempVector = Vector3<float>(0,0,0);

			for(j = 0; j < CONTROL_POINT_COUNT; j++)
			{					// n! / !i * (n - i)!
				tempVector += controlPoints[j] * ((nFactorial / (Factorial(j) * Factorial(n - j))) * 
							  pow((1 - currentTimeStep),  n - j) * pow(currentTimeStep, j));
			}

			pointsOnTheCurve.push_back(tempVector);
			currentTimeStep += timeStepIncrement;
		}

	}

	// Draws the Curve
	void Draw(void) 
	{

		glBegin(GL_LINE_STRIP); 
		glColor3f(0,1,.2);
		for(unsigned __int8 i = 0; i < pointsOnTheCurve.size(); i++)
		{
			glVertex3f(pointsOnTheCurve[i].X(), pointsOnTheCurve[i].Y(), pointsOnTheCurve[i].Z());
		}
		glEnd();
	}

};

#endif